<script setup>
import { ref, watch, onBeforeUnmount } from 'vue'

// 响应变量
const isOpen = ref(false) // Dropdown 开启/关闭状态
const dropdownRef = ref(null) // 下拉元素的Ref

// Toggle dropdown open/close state
const toggleDropdown = () => {
  isOpen.value = !isOpen.value
}

// 当点击外部时关闭下拉菜单
const closeDropdown = (event) => {
  if (!dropdownRef.value.contains(event.target)) {
    isOpen.value = false
  }
}

// Dropdown 添加事件监听/取消事件监听
watch(isOpen, (newVal) => {
  if (newVal) {
    document.addEventListener('click', closeDropdown)
  } else {
    document.removeEventListener('click', closeDropdown)
  }
})

onBeforeUnmount(() => {
  document.removeEventListener('click', closeDropdown)
})

defineExpose({ toggleDropdown })
</script>

<template>
  <div ref="dropdownRef" class="dropdown">
    <div class="dropdown-link" @click="toggleDropdown">
      <slot></slot>
    </div>
    <!-- 下拉内容 -->
    <Transition name="down">
      <div class="down-container" v-if="isOpen">
        <div class="dropdown-menu">
          <slot name="menu"></slot>
        </div>
      </div>
    </Transition>
  </div>
</template>

<style lang="scss" scoped>
.dropdown {
  position: relative;
}
.dropdown-link {
  cursor: pointer;
}
.down-container {
  position: relative;
}
.dropdown-menu {
  min-width: 110px;
  position: absolute;
  right: 50%;
  transform: translate(40px, 15px);
  background-color: rgba(255, 255, 255, 1);
  backdrop-filter: blur(20px);
  box-shadow: 0 6px 20px 0 rgba(0, 0, 0, 0.1);
  z-index: 1001;
  padding: 10px 0;
  border-radius: 8px;
  text-align: center;
}

/* 进入起点&离开终点 */
.down-enter-from,
.down-leave-to {
  transform: translateY(-15px);
  opacity: 0;
}
.down-enter-active,
.down-leave-active {
  transition: all 0.3s;
}
/* 进入终点&离开起点 */
.down-enter-to,
.down-leave-from {
  transform: translateY(0);
  opacity: 1;
}
</style>
